#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include "bmock.hpp"
#include "bmock_in_out_raw_mem.hpp"
#include "bmock_control_tools_mock.hpp"
#include "bmock_util.hpp"

static void f(const char* const str) {
	MOCK_VOID(1,(IN(str)));
}
static void g(char *const str) {
	MOCK_VOID(1,(OUT(str)));
}
static void h(char *const str) {
	MOCK_VOID(1,(IN_OUT(str)));
}

static const char        s_str[]         = "qwertyuiop[]";
static const char        sstr_name[]     = "str";
static char              s_str_exp[]     = "asdfghjkl;'zxcvbnm,.";

struct in_string_argument2 {
	in_string_argument2() {
		BMOCK_CREATE_MOCK(*);
	}
};

BMOCK_TEST(in_string_argument2,test_char) {
	BOOST_CHECK_NO_THROW(BMOCK_EXPECT(f(s_str)));
	BMOCK_REPLAY;
	BOOST_CHECK_NO_THROW(f(s_str));
	BMOCK_VERIFY;
}

struct out_string_argument2 {
	out_string_argument2() {
		std::fill_n(buf,L,0);
		BMOCK_CREATE_MOCK(*);
	}

	static const size_t L = sizeof(s_str);
	char buf[L];
};

const size_t out_string_argument2::L;

BMOCK_TEST(out_string_argument2,test_char) {
	BOOST_CHECK_NO_THROW(BMOCK_EXPECT(g((char *)s_str)));
	BMOCK_REPLAY;
	BOOST_CHECK_NO_THROW(g(buf));
	BMOCK_VERIFY;
	BOOST_CHECK_EQUAL(bmock::mismatch_at(buf,buf+L,s_str),L);
}

struct in_out_string_argument2 {
	in_out_string_argument2()
		:str1(bmock::in_out_str(s_str,s_str_exp))
	{
		BMOCK_CREATE_MOCK(*);
		strcpy(buf,s_str);
	}

	static const size_t        L = sizeof(s_str_exp);
	char                       buf[L];
	bmock::in_out_raw_mem_descr<char> str1;
};

const size_t in_out_string_argument2::L;

BMOCK_TEST(in_out_string_argument2,test_char_OK) {
	BOOST_CHECK_NO_THROW(BMOCK_EXPECT(h(str1)));
	BMOCK_REPLAY;
	BOOST_CHECK_NO_THROW(h(buf));
	BMOCK_VERIFY;
	BOOST_CHECK_EQUAL(bmock::mismatch_at(buf,buf+L,s_str_exp),L);
}

BOOST_AUTO_TEST_CASE(testInOutStringArgument_char_InvalidLength2) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const size_t            L1     = sizeof(s_str);
	const char              name[] = "str";
	char                    buf[L1+sizeof(size_t)];
	const bmock::location          loc(__FILE__,__LINE__+9);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(bmock::message(bmock::RAW_MEM_PAD,name),loc));
	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->abort(loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		std::fill_n(buf,sizeof(buf),0);
		strcpy(buf,s_str);
		BOOST_CHECK_THROW(__BMOCK_EXPECT_C(c1,h((char *)buf)),bmock::location);
		__BMOCK_REPLAY_C(c1);
		__BMOCK_VERIFY_C(c1);
	}
	__BMOCK_VERIFY_C(c);
}


